#!/bin/bash
# - upstream_repo
# - arch
# upstream_commit
# upstream_branch
# custom_repo_name
# custom_repo_addr
# mount_repo_name
# mount_repo_addr
# repo_addr
# whether_email
# compat_os
# SRPMs jobs not use upstream_repo, Git jobs use all.
# user can add mount_repo_name and mount_repo_addr to setup
# local repo, value can be an array

. $LKP_SRC/lib/debug.sh
. $LKP_SRC/lib/upload.sh
. $LKP_SRC/lib/rpm.sh
. $LKP_SRC/lib/email.sh

: "${compat_os:=budding-openeuler}"

([ -n "$depend_upstream_repo" ] || [ -n "$custom_repo_name" ]) || die "custom_repo_name is empty"

dest_dir="/rpm/upload/${os}-${os_version}/${custom_repo_name}"
rpmdev_dir="/home/lkp/rpmbuild"

declare -a reverse_depends
die()
{
	rpmbuild_email "rpmbuild_failed"
	echo "$@"
	exit 99
}

from_git()
{
	package_name=${upstream_repo##*/}
	package_name=${package_name%%.git*}
	rpm_dest="${dest_dir}/${os_arch}/Packages"
	tmp_rpm_dest="/tmp${rpm_dest}/$id"
	src_rpm_dest="${dest_dir}/source/Packages"

	init_workspace
	download_upstream_repo
}

echo_commit_info()
{
	for i in $(git_pretty_format "$1" "$2" "$3")
	do
		echo "$4+=('"$i"')"
	done
}

get_merge_info()
{
	declare -a name
	declare -a email
	declare -A email_name_hash

	name=(liping wangyong)
	email=(liping136@huawei.com wangyong187@huawei.com)

#	eval $(echo_commit_info "--no-color" "%ae" "$1" email)
#	eval $(echo_commit_info "--no-color" "%ce" "$1" email)
#	eval $(echo_commit_info "-n1" "%ae" "$2" email)
#	eval $(echo_commit_info "-n1" "%ce" "$2" email)
#
#	IFS_SAVE=$IFS
#	IFS=$'\n'
#	eval $(echo_commit_info "--no-color" "%an" "$1" name)
#	eval $(echo_commit_info "--no-color" "%cn" "$1" name)
#	eval $(echo_commit_info "-n1" "%an" "$2" name)
#	eval $(echo_commit_info "-n1" "%cn" "$2" name)
#	IFS=$IFS_SAVE

	for key in "${!email[@]}"
	do
		[[ "${email[$key]}" =~ ^noreply ]] && continue
		[[ "${email[$key]}" =~ ^80474298@qq.com ]] && continue
		email_name_hash["${email[$key]}"]="${name[$key]}"
	done

	IFS_SAVE=$IFS
	IFS=$';'
	eval $3='"${!email_name_hash[*]}"'
	IFS=$IFS_SAVE

	IFS_SAVE=$IFS
	IFS=$','
	eval $4='"${email_name_hash[*]}"'
	IFS=$IFS_SAVE
}

git_pretty_format()
{
	curl -sS -H 'Content-Type: Application/json' -XPOST "$REMOTE_GIT_HOST:$REMOTE_GIT_PORT"'/git_command' -d '{"git_repo": "'${upstream_dir}/${upstream_repo}.git'", "git_command": ["git-log","'$1'","--pretty=format:'$2'", "'$3'"]}'
}

is_git_merge()
{
	curl -sS -H 'Content-Type: Application/json' -XPOST "$REMOTE_GIT_HOST:$REMOTE_GIT_PORT"'/git_command' -d '{"git_repo": "'${upstream_dir}/${upstream_repo}.git'", "git_command": ["git-show", "--no-patch", "--format=%p", "'$1'"]}'
}

rpmbuild_email()
{
	[ -n "$whether_email" ] || return
	if [[ $(is_git_merge "$upstream_commit" | wc -w) -eq 1 ]]; then
		get_merge_info "" "${upstream_commit}" author_email author_name
	else
		parent_commit=$(is_git_merge $upstream_commit | sed 's/\ /.../')
		get_merge_info "${parent_commit}" "${upstream_commit}" author_email author_name
	fi

	if [ -n "$depend_job_id" ]; then
		send_email "reverse_rpmbuild"
	else
		send_email $1
	fi
}

from_srpm()
{
	[ -n "$repo_addr" ] || die "repo_addr is empty"

	rpm_dest="${dest_dir}/${os_arch}/Packages"
	src_rpm_dest="${dest_dir}/source/Packages"

	install_srpm
}

init_workspace()
{
	[ -d /home/lkp ] ||
		{
			mkdir -m 700 /home/lkp
			chown lkp /home/lkp
			chgrp lkp /home/lkp
		}
	# generate workspace in ${HOME}
	su lkp -c rpmdev-setuptree
}

download_upstream_repo()
{
	local url="git://${GIT_SERVER}/${upstream_dir}/${upstream_repo}"
	local ref=""

	git clone -q "$url" 2>/dev/null || git clone -q "$upstream_repo" || die "clone git repo ${package_name} failed: $url"
	cd "$package_name" || exit
	pr=$(echo $pr_merge_reference_name |awk '{split($0,a,"/");print a[3]}')
	[ -n "${pr_merge_reference_name}" ] && git fetch origin pull/$pr/head
	[ -n "${upstream_branch}" ] && ref="${upstream_branch}"
	[ -n "${upstream_commit}" ] && ref="${upstream_commit}"
	[ -n "${ref}" ] && {
		git checkout -q "${ref}" || die "checkout git repo ${package_name} to ${ref} failed"
	}
	filelist=($(git ls-files))

	for pkgfile in "${filelist[@]}"
	do
		local dir="SOURCES"

		echo "$pkgfile" | grep -v "\/" | grep -q -E "\\.spec$" && dir="SPECS"
		mv "$pkgfile" "${rpmdev_dir}/${dir}/"
	done
}

add_user_mock()
{
	useradd mock
	useradd mockbuild
}

install_srpm()
{
	add_user_mock

	su lkp -c "rpm -i --nosignature ${repo_addr} >/dev/null" || su lkp -c "rpm -i --nosignature ${repo_addr}/${upstream_repo} >/dev/null" || die "failed to install source rpm: ${repo_addr}/${upstream_repo}"
}

build_rpm()
{
	export spec_dir="${rpmdev_dir}/SPECS"
	[ -n "$package_name" ] &&
		{
			# HTTP is proxy cache friendly
			sed -i 's/^\(Source[^ ]*:[ \t]*\)https/\1http/g' "$(grep http -rl "$spec_dir/"*.spec)"
		}
	startTime=$(date +%Y-%m-%d-%H:%M)
	startTime_s=$(date +%s)
	fix_on_distro
	[ -n "$depend_upstream_repo" ] && localinstall_dependent_package
	# Install build dependencies
	yum-builddep -y "$spec_dir"/*.spec 2>&1 || die "failed to solve dependencies"
	# Download tar.gz to default path ${HOME}/rpmbuild/SOURCE
	[ -n "$package_name" ] &&
		{
			su lkp -c "spectool -g -R $spec_dir/"*.spec || die "failed to download source file"
		}
	# Build source and binary packages
	su - lkp -c "rpmbuild -ba --quiet ${spec_dir}/*.spec" || die "failed to build rpms"
	endTime=$(date +%Y-%m-%d-%H:%M)
	endTime_s=$(date +%s)

	sumTime=$[ $endTime_s - $startTime_s ]

	echo "RPM build START TIME: $startTime, END TIME: $endTime, Total duration: $sumTime seconds"
	find /${rpmdev_dir}/BUILD/*/ -maxdepth 1 -type d -name "tests" | grep "tests"
	[ $? = 0 ] && echo "All test cases are passed."
}

localinstall_dependent_package()
{
	yum install -y wget
	mkdir /tmp/rpm
	cd /tmp/rpm
	wget -c -r -np -nd -R index.html "${SRV_HTTP_PROTOCOL:-https}://${SCHED_HOST}:${SRV_HTTP_RPM_PORT:-20012}$depend_rpm_dest/" || die "failed to download local depend rpms"
	yum localinstall -y *.rpm || die "failed to local install rpms"
}
show_rpm_files()
{
	find ${rpmdev_dir}/RPMS -type f -name "*.rpm"
}

show_src_rpm_files()
{
	find ${rpmdev_dir}/SRPMS -type f -name "*.src.rpm"
}

show_spec_file()
{
	find ${rpmdev_dir}/SPECS -type f -name "*.spec"
}

upload_rpm_pkg()
{
	local rpm_file
	for rpm_file in $(show_rpm_files)
	do
		upload_one_curl ${rpm_file} ${rpm_dest}
		[ -n "$pr_merge_reference_name" ] && upload_one_curl ${rpm_file} ${tmp_rpm_dest}
	done

	local src_rpm_file
	for src_rpm_file in $(show_src_rpm_files)
	do
		upload_one_curl ${src_rpm_file} ${src_rpm_dest}
	done
}

upload_spec_file()
{
	for spec_file in $(show_spec_file)
	do
		upload_one_curl ${spec_file} ${result_root}
	done
}

handle_rpm_list()
{
	rpm_list=($(show_rpm_files | xargs basename -a))
	srpm_list=($(show_src_rpm_files | xargs basename -a))
	full_list=("${rpm_list[@]}" "${srpm_list[@]}")

	for rpm_index in "${!full_list[@]}"
	do
		rpm_name="${full_list["${rpm_index}"]}"
		full_list["${rpm_index}"]="\"/srv${rpm_dest}/${rpm_name}\""
		[[ ${rpm_name} =~ "src.rpm" ]] && full_list["${rpm_index}"]="\"/srv${src_rpm_dest}/${rpm_name}\""
	done

	full_list=$(echo "${full_list[@]}" | sed 's; ;,;g')
}

update_repo_mq()
{
	handle_rpm_list

	curl -sS -H 'Content-Type: Application/json' -XPOST "${UPDATE_REPO_HOST}:${UPDATE_REPO_PORT}/upload" \
		-d "{\"upload_rpms\": ["${full_list}"], \"job_id\": \"${id}\"}"
}

find_reverse_depends()
{
	local j
	rpm_name=${upstream_repo##*/}
	for rev_rpm in $(dnf repoquery -q --whatrequires "${rpm_name}")
	do
		rev_rpm=${rev_rpm%%:*}
		rev_rpm=${rev_rpm%-*}
		reverse_depends[j++]=$rev_rpm
	done
}

notify_scheduler_submit()
{
	content='{"depend_job_id":"'${id}'","depend_rpm_dest":"'${tmp_rpm_dest}'","reverse_depends":"'${reverse_depends[@]}'"}'
	curl -sS -XPOST "http://$SCHED_HOST:$SCHED_PORT/rpmbuild/submit_reverse_depend_jobs" -d "$content"
}

detect_reverse_depends()
{
	[ "$upstream_dir" != "openeuler" ] && return
	find_reverse_depends
	notify_scheduler_submit
}

update_srpm_list()
{
	srpm=${repo_addr##*/}
	data="{\"srpms\": [{\"os\": \"${compat_os}\", \"srpm\": \"${srpm}\", \"build_state\": \"1\"}], \"job_id\": \"${id}\", \"type\": \"update\"}"

	curl -sS -H 'Content-Type: Application/json' -XPOST ${SCHED_HOST}:${SCHED_PORT}/repo/set-srpm-info -d "${data}"
}

add_repo
yum_repo_retry
if [ -n "$upstream_repo" ]; then
	from_git
else
	from_srpm
fi
upload_spec_file
build_rpm
[ $? = 0 ] && update_srpm_list
[ -n "$depend_upstream_repo" ] && exit 0
detect_reverse_depends
upload_rpm_pkg
update_repo_mq
#[ -n "$upstream_commit" ] && rpmbuild_email "rpmbuild_success"
#exit 0
